#include "types.h"
#include "param.h"
#include "memlayout.h"
#include "riscv.h"
#include "defs.h"
#include "uart.h"
#include "proc.h"        // 添加：用于 struct proc, struct cpu, proc 数组等
#include "spinlock.h"    // 添加：用于 intr_on() 等

// 前向声明：swtch 函数（在 swtch.S 中定义）
void swtch(struct context*, struct context*);

volatile static int started = 0;

void
main()
{
  if (r_tp() == 0) {
    consoleinit();
    printfinit();

    printf("\n");
    printf("xv6 kernel is booting\n");
    printf("\n");

    // 正常顺序：先初始化内存分配器（此时分页未启用，直接访问物理地址）
    kinit();
    
    // 然后创建页表（需要调用 kalloc()）
    kvminit();
    
    // 在启用分页之前，先设置陷阱向量，确保异常处理程序已就绪
    trapinit();
    trapinithart();  // 设置 stvec，但不打开中断
    
    // 最后启用分页
    kvminithart();
    
    // 启用分页后，现在可以安全地打开中断
    w_sstatus(r_sstatus() | SSTATUS_SIE);

    printf("hart 0 starting\n");

    // 初始化文件系统（在进程初始化之前）
    int has_disk = 0;
    
    // 优先使用ramdisk（用于测试）
    ramdisk_init();
    set_use_ramdisk(1);
    has_disk = 1;
    printf("Using ramdisk for file system\n");
    
    // 如果virtio可用，也可以使用
    if(virtio_disk_init() == 0) {
      printf("virtio disk also available\n");
    }
    
    binit();              // 初始化块缓存
    iinit(ROOTDEV);       // 初始化inode缓存
    fileinit();           // 初始化文件描述符表
    devinit();            // 初始化设备驱动
    
    if(has_disk) {
      // 初始化文件系统：需要先创建文件系统镜像
      // 这里简化处理，直接初始化（实际需要mkfs）
      printf("Initializing file system on ramdisk...\n");
      // fsinit(ROOTDEV);  // 暂时注释，需要先创建文件系统镜像
      
      // 即使没有文件系统镜像，也需要初始化日志系统用于测试
      // 创建一个默认的 superblock 用于日志初始化
      extern struct superblock sb;
      sb.logstart = 2;   // 日志从块 2 开始
      sb.nlog = LOGSIZE; // 使用默认的日志大小
      
      // 初始化日志系统
      initlog(ROOTDEV, &sb);
      
      printf("File system ready (ramdisk)\n");
    }

    // 初始化进程子系统
    procinit();

    // 文件系统测试
    extern void fs_tests_start(void);
    fs_tests_start();

    __sync_synchronize();
    started = 1;
    
    // 测试完成后，main空转
    printf("\nMain loop spinning...\n");
    for (;;) {
      // 空转，等待中断或其他事件
      asm volatile("wfi");  // Wait for interrupt
    }
  } else {
    while (started == 0) { }
    __sync_synchronize();
    kvminithart();
    trapinithart();
    w_sstatus(r_sstatus() | SSTATUS_SIE);  // 也在这里打开中断
    printf("hart %d starting\n", (int)r_tp());
    // 其他hart也空转
    for (;;) {
      asm volatile("wfi");
    }
  }

}